// Behavior Created by Liferose
#region Usings
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;

using Bots.Grind;
using Buddy.Coroutines;
using CommonBehaviors.Actions;
using Honorbuddy.QuestBehaviorCore;
using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.CommonBot.POI;
using Styx.Pathing;
using Styx.CommonBot.Profiles;
using Styx.CommonBot.Routines;
using Styx.Helpers;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.World;
using Styx.WoWInternals.WoWObjects;

using Action = Styx.TreeSharp.Action;
#endregion


namespace Honorbuddy.Quest_Behaviors.LifeProject.SpecificQuests.Kalimdor.Azshara
{
    [CustomBehaviorFileName(@"LifeProject\14155-Arboricide")]
    public class Arboricide : QuestBehaviorBase
    {
        #region Constructor and Argument Processing
        public Arboricide(Dictionary<string, string> args)
            : base(args)
        {
            QBCLog.BehaviorLoggingContext = this;

            try
            {
                QuestId = 14155;
                QuestRequirementComplete = QuestCompleteRequirement.NotComplete;
                QuestRequirementInLog = QuestInLogRequirement.InLog;
				AncientSpot = new WoWPoint(2611.143, -4619.896, 144.8904);
            }

            catch (Exception except)
            {
                // Maintenance problems occur for a number of reasons.  The primary two are...
                // * Changes were made to the behavior, and boundary conditions weren't properly tested.
                // * The Honorbuddy core was changed, and the behavior wasn't adjusted for the new changes.
                // In any case, we pinpoint the source of the problem area here, and hopefully it can be quickly
                // resolved.
                QBCLog.Exception(except);
                IsAttributeProblem = true;
            }
        }

        protected override void EvaluateUsage_DeprecatedAttributes(XElement xElement)
        {
        }

        protected override void EvaluateUsage_SemanticCoherency(XElement xElement)
        {
        }

        public int QuestId { get; private set; }
        public QuestCompleteRequirement QuestRequirementComplete { get; private set; }
        public QuestInLogRequirement QuestRequirementInLog { get; private set; }
		public WoWPoint AncientSpot { get; private set; }
		public WoWUnit Target;
        #endregion

        #region Private and Convenience variables
        public LocalPlayer Me { get { return (StyxWoW.Me); } }
        #endregion

		private WoWUnit Ancient
		{
			get
			{
				return ObjectManager.GetObjectsOfType<WoWUnit>()
					.Where(u => (u.Entry == 35198) && u.IsAlive)
					.OrderBy(u => u.Distance).FirstOrDefault();
			}
		}

		private WoWUnit Distraction
		{
			get
			{
				return ObjectManager.GetObjectsOfType<WoWUnit>()
					.Where(u => (u.Entry != 35198) && u.GotTarget && u.IsAlive && u.CurrentTarget == Me.CharmedUnit)
					.OrderBy(u => u.Distance).FirstOrDefault();
			}
		}

		private bool Buzzsaw()
		{
			return
				Lua.GetReturnVal<bool>("if GetPetActionCooldown(1) == 0 then CastPetAction(1) return 1 else return nil end", 0);
		}

		private bool FlingBlade()
		{
			return
				Lua.GetReturnVal<bool>("if GetPetActionCooldown(2) == 0 then CastPetAction(2) return 1 else return nil end", 0);
		}

		private bool GernadeLauncher()
		{
			return
				Lua.GetReturnVal<bool>("if GetPetActionCooldown(3) == 0 then CastPetAction(3) return 1 else return nil end", 0);
		}

		private bool Recharge()
		{
			return
				Lua.GetReturnVal<bool>("if GetPetActionCooldown(6) == 0 then CastPetAction(6) return 1 else return nil end", 0);
		}

        public override void OnStart()
        {
            var isBehaviorShouldRun = OnStart_QuestBehaviorCore(string.Empty);

            if (isBehaviorShouldRun)
            {
                LevelBot.BehaviorFlags &=
                    ~(BehaviorFlags.Combat | BehaviorFlags.Vendor);
            }
        }

        protected override Composite CreateBehavior_CombatOnly()
        {
            return new PrioritySelector(
                new Decorator(context => Query.IsInVehicle(),
                    new ActionAlwaysSucceed())
                );
        }

        protected override Composite CreateMainBehavior()
        {
			return new PrioritySelector(
				// We're done, delegate to profile
				new Decorator(context => (Me.IsQuestComplete(QuestId) || !Query.IsInVehicle()),
					new Sequence(
						new Action(context => { BehaviorDone(); })
						)
					),
				// Mob Selection
				new Action(context =>
					{	var Distraction =
						ObjectManager.GetObjectsOfType<WoWUnit>()
						.Where(u => (u.Entry != 35198) && u.GotTarget && u.IsAlive && u.CurrentTarget == Me.CharmedUnit)
						.OrderBy(u => u.Distance).FirstOrDefault();
						if (Distraction != null)
						{
							Target = Distraction;
							return RunStatus.Failure;
						}
						else if (Ancient != null)
						{
							Target = Ancient;
							return RunStatus.Failure;
						}
						else
						{
							return RunStatus.Failure;
						}
					}),
				new Decorator(context => Target != null,
					new PrioritySelector(
						// Lets stop dying, shall we?
						new Decorator(context => (!SpellManager.GlobalCooldown) && (Me.CharmedUnit.CurrentHealth < 350),
							new Action(context => Recharge() ? RunStatus.Success : RunStatus.Failure)
							),
						new Decorator(context => !Target.WithinInteractRange && Target != null && Target.IsAlive,
							new Action(context => { Navigator.MoveTo(Target.Location); })
							),
						new Decorator(context => Me.CharmedUnit.IsMoving,
							new Action(context => { WoWMovement.MoveStop(); })							
							),
						new Decorator(context => !SpellManager.GlobalCooldown && Target != null && Target.IsAlive,
							new Sequence(
								new Action(context => { Target.Target(); }),
								new Action(context => { Target.Face(); }),
								// The ancient is big enough to really just spam this
								new Action(context => {
									if (Target == Ancient)
									{
										GernadeLauncher();
									}
								}),
								new WaitContinue(TimeSpan.FromMilliseconds(500), context => false, new ActionAlwaysSucceed()),
								new Action(context => Buzzsaw() ? RunStatus.Success : RunStatus.Failure),
								new WaitContinue(TimeSpan.FromMilliseconds(1500), context => false, new ActionAlwaysSucceed()),
								new Action(context => FlingBlade() ? RunStatus.Success : RunStatus.Failure),
								new WaitContinue(TimeSpan.FromMilliseconds(500), context => false, new ActionAlwaysSucceed())
								)
							)
						)
					),
				// We should find the ancient(s), the pegasus galaxy depends on it!
				new Decorator(context => Ancient == null && Target == null && !Navigator.AtLocation(AncientSpot),
                    new UtilityBehaviorPS.MoveTo(context => AncientSpot, context => "Ancient Location", context => MovementBy)
                    )
				);
        }
    }
}
